package com.example.system.controller;

import com.example.system.common.Result;
import com.example.system.entity.Health;
import com.example.system.entity.Sleep;
import com.example.system.exception.CustomException;
import com.example.system.service.impl.HealthServiceImpl;
import com.example.system.service.impl.SleepServiceImpl;
import com.example.system.service.impl.UserServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.messaging.handler.annotation.MessageMapping;
import org.springframework.messaging.handler.annotation.SendTo;
import org.springframework.web.bind.annotation.*;

import java.time.LocalDateTime;
import java.util.Map;
import java.util.Random;
import java.util.concurrent.*;

@CrossOrigin
@RestController
@RequestMapping("/process")
public class ProcessController {
    @Autowired
    HealthServiceImpl healthService;

    @Autowired
    SleepServiceImpl sleepService;

    @Autowired
    UserServiceImpl userService;

    // 创建一个ScheduledExecutorService来管理定时任务
    private final ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(10);

    private final Map<String, ScheduledFuture<?>> processesToRecordHealth = new ConcurrentHashMap<>();

    private final Map<String, LocalDateTime> sleepRecords = new ConcurrentHashMap<>();

    /**
     * 根据id启动假数据自动生成线程
     *
     * @param id
     * @return Result
     */
    @PostMapping("/start/healthRecord/{id}")
    public Result startHealthRecordProcess(@PathVariable String id) {
        if (processesToRecordHealth.containsKey(id)) {
            return Result.error("当前用户正在记录健康信息");
        }
        Random rand = new Random();
        // 定义一个Runnable任务，这里只是打印了一条消息和模拟了等待时间
        // 在实际应用中，这里会包含数据库操作等逻辑
        Runnable task = () -> {
            System.out.println("Processing health data for ID: " + id);
            Health health = new Health();
            health.setUserId(Integer.valueOf(id));
            health.setHeartRate(rand.nextInt(200) + 1);
            health.setBloodPressureSystolic(rand.nextInt(300) + 1);
            health.setBloodPressureRelease(rand.nextInt(300) + 1);
            health.setTime(LocalDateTime.now());
            healthService.addHealthByHealth(health);
            try {
                TimeUnit.SECONDS.sleep(5); // 模拟任务执行时间
            } catch (InterruptedException e) {
                // 如果任务被中断，则设置当前线程的中断状态
                Thread.currentThread().interrupt();
            }
            // 这里可以添加实际的数据库操作代码
        };

        // 使用scheduler提交一个定时任务，该任务从0秒后开始执行，之后每5秒执行一次
        ScheduledFuture<?> future = scheduler.scheduleAtFixedRate(task, 0, 5, TimeUnit.SECONDS);

        processesToRecordHealth.put(id, future);

        return Result.success("Process started for ID: " + id);
    }

    @PostMapping("/start/sleepRecord/{id}")
    public Result startSleepRecordProcess(@PathVariable String id) {
        if (sleepRecords.containsKey(id)) {
            return Result.error("当前用户正在记录睡眠信息");
        }
        if (!userService.existsUserById(Integer.valueOf(id))) {
            return Result.error("当前用户不存在");
        }
        this.sleepRecords.put(id, LocalDateTime.now());
        return Result.success("已开始记录睡眠信息，用户ID为: " + id);
    }

    // 处理停止进程的POST请求

    /**
     * 根据id停止假数据自动生成进程
     *
     * @param id
     * @return Result
     */
    @PostMapping("/stop/healthRecord/{id}")
    public Result stopHealthRecordProcess(@PathVariable String id) {
        // 从映射中根据ID查找对应的ScheduledFuture
        ScheduledFuture<?> future = processesToRecordHealth.remove(id);

        // 如果找到了对应的任务并且任务尚未完成（即没有被取消或自然结束）
        if (future != null && !future.isDone()) {
            // 尝试取消任务，但不中断正在执行的任务（如果任务正在执行，它会继续执行直到完成）
            // 如果需要立即停止正在执行的任务，可以考虑使用future.cancel(true)
            boolean cancelled = future.cancel(false);

            // 如果任务被成功取消，则返回HTTP OK响应和一条消息
            // 注意：即使cancelled为true，也不意味着任务一定被取消了，特别是如果任务正在执行且future.cancel(false)被调用
            return Result.success(id + "号健康记录进程已结束");
        } else {
            return Result.error(id + "号用户尚未开始记录健康信息");
        }
    }

    @PostMapping("/stop/sleepRecord/{id}")
    public Result stopSleepRecordProcess(@PathVariable String id) {
        if (!this.sleepRecords.containsKey(id)) {
            return Result.error(id + "号用户尚未开始记录睡眠信息");
        } else {
            LocalDateTime startTime = this.sleepRecords.get(id);
            this.sleepRecords.remove(id);
            Sleep sleep = new Sleep();
            sleep.setSleepBegin(startTime);
            sleep.setSleepEnd(LocalDateTime.now());
            sleep.setUserId(Integer.valueOf(id));
            try {
                sleepService.addSleepBySleep(sleep);
            } catch (CustomException e) {
                return Result.error(e.getMsg());
            }
            return Result.success("已结束" + id + "号用户的睡眠记录");
        }
    }

}
